import MainLine from "../../src/utils/MainLine.js";
import pool from "./createPool.js";
import LocalRunner from "./Factory.js";
import {
    interval,
    take,
    map,
    mergeMap,
    timer,
    switchMap,
} from "https://cdn.jsdelivr.net/npm/rxjs/+esm";
import { sleep } from "./utils/sleep.js";
import color from "./color.js";
window.pool = pool;
new Vue({
    el: "#app",
    data() {
        const startTime = new Date().getTime();
        const ganttData = {
            startTime, //时间轴开始时间，固定不变
            endTime: startTime, //时间结束时间
            datas: [], // gantt数据
            timelines: [],
            markOpacity: 70,
            prepared: false,
            stopTime: startTime,
            initTime: startTime,
        };
        const system = {
            pool,
            mainline: new MainLine({ lazy: true }),
            WorkingLine: new MainLine({ lazy: true }),
            timeScale: 1000,
            timeSpace: 300,
            Index: {
                factory: 0,
                task: 0,
            },
        };
        return { ...ganttData, ...system };
    },
    async mounted() {
        this.pool.on({
            start: () => {
                this.stopTime += this.timeSpace * this.timeScale;
                this.initTime = new Date().getTime();
                this.addMark({ text: "重启", color: color.blue.DEFAULT });
            },
            drain: () => {
                this.stopTime +=
                    (new Date().getTime() - this.initTime) * this.timeScale;
                this.initTime = new Date().getTime();
                this.addMark({ text: "暂停中", color: color.pink.light });
            },
            stop: () => {
                this.addMark({ text: "停止", color: color.blue.dark });
                this.stopTime +=
                    (new Date().getTime() - this.initTime) * this.timeScale;
                this.initTime = new Date().getTime();
            },
        });
        timer(100)
            .pipe(
                switchMap((i) => interval(20)),
                take(5),
                map((i) => {
                    this.addFactory();
                })
            )
            .subscribe();

        this.RunAWhile();
        this.prepared = true;
    },
    methods: {
        RunAWhile() {
            this.WorkingLine.addEvent(() => {
                return new Promise((resolve) => {
                    this.initTime = new Date().getTime();
                    this.addMark({
                        text: "开始",
                        color: color.blue.light,
                    });
                    interval(50)
                        .pipe(
                            take(40),
                            mergeMap(() => this.doWork())
                        )
                        .subscribe({
                            complete: () => {
                                this.addMark({
                                    text: "完成",
                                    color: color.pink.DEFAULT,
                                });
                                // 多加 500 是为了形成段落
                                this.stopTime +=
                                    (new Date().getTime() -
                                        this.initTime +
                                        this.timeSpace) *
                                    this.timeScale;
                                resolve();
                            },
                        });
                });
            });
        },
        async doWork() {
            return this.pool.use(async (runner) => {
                const start = new Date().getTime();
                const startFakeTime =
                    (start - this.initTime) * this.timeScale + this.stopTime;
                await sleep(400);
                const diff = new Date().getTime() - start;
                const data = {
                    name: this.Index.task++,
                    start: startFakeTime,
                    end: diff * this.timeScale + startFakeTime,
                };
                this.datas[runner.index].gtArray.push(data);
                if (data.end > this.endTime - this.timeSpace * this.timeScale) {
                    this.endTime += this.timeScale * this.timeSpace * 10;
                    this.lookForward();
                }
                this.pool.log.info(runner.index, "done", this.Index.task);
            });
        },
        lookForward() {
            if (this.$refs.gantt) {
                this.$nextTick(() => {
                    const el = this.$refs.gantt;
                    this.$refs.gantt.scrollToPostionHandle({
                        y: 0,
                        x: el.avialableScrollLeft,
                    });
                });
            }
        },
        addFactory() {
            const id = this.Index.factory++;
            this.pool.addFactory(new LocalRunner({ index: id }));
            this.datas.push({
                id,
                name: id,
                gtArray: [],
            });
            this.addMark({ text: id + " add", color: color.pink.dark });
        },
        addMark({ text, color }) {
            const time =
                (new Date().getTime() - this.initTime) * this.timeScale +
                this.stopTime;
            this.timelines.push({
                text,
                time,
                color,
                index: this.timelines.length % (this.datas.length + 1),
            });
            if (time > this.endTime - this.timeSpace * this.timeScale) {
                this.endTime += 5 * this.timeSpace * this.timeScale;
                this.lookForward();
            }
        },
        Stop() {
            this.mainline.addEvent(() => {
                return pool.drain();
            });
        },
        KeepGoing() {
            this.mainline.addEvent(() => {
                return pool.start();
            });
        },
    },
});
